{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Logistic Regression.ipynb",
      "provenance": [],
      "collapsed_sections": [
        "Ix8W-GEhlqkL"
      ],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ofWo9K6fTUUt",
        "colab_type": "text"
      },
      "source": [
        "# Logistic Regression\n",
        "\n",
        "In this example we will see how to classify images as horses or people using logistic regression. The tutorial builds upon the concepts introduced in the [Objax basics tutorial](Objax_Basics.html). Consider reading that tutorial first, or you can always go back."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u0a3VjeVqa-N",
        "colab_type": "text"
      },
      "source": [
        "## Imports\n",
        "\n",
        "First, we import the modules we will use in our code."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-TmyQd4ZnZpg",
        "colab_type": "code",
        "colab": {},
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767875325,
          "user_tz": 420,
          "elapsed": 549,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        }
      },
      "source": [
        "%pip --quiet install objax\n",
        "\n",
        "import matplotlib.pyplot as plt\n",
        "import os\n",
        "\n",
        "import numpy as np\n",
        "import tensorflow_datasets as tfds\n",
        "\n",
        "import objax\n",
        "from objax.util import EasyDict"
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZIdlxcnWqlcL",
        "colab_type": "text"
      },
      "source": [
        "## Loading the Dataset\n",
        "\n",
        "Next, we will load the \"[horses_or_humans](https://www.tensorflow.org/datasets/catalog/horses_or_humans)\" dataset from [TensorFlow DataSets](https://www.tensorflow.org/datasets/api_docs/python/tfds).\n",
        "\n",
        "The ``prepare`` method downscales the image by 3x to reduce training time, flattens each image to a vector, and rescales each pixel value to [-1,1]."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RvXEBRtgSEY1",
        "colab_type": "code",
        "colab": {},
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767886453,
          "user_tz": 420,
          "elapsed": 8242,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        }
      },
      "source": [
        "# Data: train has 1027 images - test has 256 images\n",
        "# Each image is 300 x 300 x 3 bytes\n",
        "DATA_DIR = os.path.join(os.environ['HOME'], 'TFDS')\n",
        "data = tfds.as_numpy(tfds.load(name='horses_or_humans', batch_size=-1, data_dir=DATA_DIR))\n",
        "\n",
        "def prepare(x, downscale=3):\n",
        "  \"\"\"Normalize images to [-1, 1] and downscale them to 100x100x3 (for faster training) and flatten them.\"\"\"\n",
        "  s = x.shape\n",
        "  x = x.astype('f').reshape((s[0], s[1] // downscale, downscale, s[2] // downscale, downscale, s[3]))\n",
        "  return x.mean((2, 4)).reshape((s[0], -1)) * (1 / 127.5) - 1\n",
        "\n",
        "train = EasyDict(image=prepare(data['train']['image']), label=data['train']['label'])\n",
        "test = EasyDict(image=prepare(data['test']['image']), label=data['test']['label'])\n",
        "ndim = train.image.shape[-1]\n",
        "del data"
      ],
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GY_CRF87QnvU",
        "colab_type": "text"
      },
      "source": [
        "## Visualizing the Data\n",
        "\n",
        "Let's see a couple of the images in the dataset and their corresponding labels. Note that label ``0`` corresponds to a horse, while label ``1`` corresponds to a human."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mFshOfmlQnOG",
        "colab_type": "code",
        "colab": {
          "height": 286
        },
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767892623,
          "user_tz": 420,
          "elapsed": 553,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        },
        "outputId": "cd20b877-96ae-4c98-ca63-354bd8de64d4"
      },
      "source": [
        "#sample image of a horse.\n",
        "horse_image = np.reshape(train.image[0], [100,100,3])\n",
        "plt.imshow(horse_image)\n",
        "print(\"label for horse_image:\", train.label[0])"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "label for horse_image: 0\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\np/ClL30Jp0+fhs/nW7dicyQSwdGjR3H58mUMDw8jkUjgxRdfXOtprQrK8vC3tbVhYEDHMg0ODqKl\npWWeHmuDXC6Hhx9+GI8//jgeeughAEBTUxNGRig6bWRkBI2NjfMNURa89dZb+PGPf4yuri489thj\neP311/HEE0+sy7kC9KYJfOgAAAF5SURBVP23tbVhz549AICDBw/i1KlT63K+P//5z7Fp0yY0NDTA\n4XDgoYcewvHjx9flXK8XZXn477rrLly4cAGXL19GNpvFSy+9hP3795fj0ouGYRh46qmn0N3dja98\n5Sul8/v378eRI0cAAEeOHMGBAwfWaoolPPvssxgcHER/fz9eeukl7N27Fy+++OK6nCsANDc3o729\nHR9++CEA4NixY9i5c+e6nG9HRwdOnDiBZDIJwzBw7NgxdHd3r8u5XjfKpVx47bXXjK1btxqbN282\n/vIv/7Jcl1003nzzTQOAsXv3buPWW281br31VuO1114zJicnjb179xpbtmwx9u7da0xNTa31VK/C\nL37xi5LCbz3P9fTp08add95p7N692zhw4IARDofX7Xy//vWvG9u3bzd27dplPPHEE0Y6nV63c70e\niIefQFChEA8/gaBCIQ+/QFChkIdfIKhQyMMvEFQo5OEXCCoU8vALBBUKefgFggqFPPwCQYXi/wdH\nPhl+tTBrgQAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 600x400 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zkdQmN1WdlLD",
        "colab_type": "code",
        "colab": {
          "height": 286
        },
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767895186,
          "user_tz": 420,
          "elapsed": 572,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        },
        "outputId": "aff0a27a-0caa-4378-dd28-6e5096484d34"
      },
      "source": [
        "#sample image of a human.\n",
        "human_image = np.reshape(train.image[9], [100, 100, 3])\n",
        "plt.imshow(human_image)\n",
        "print(\"label for human_image:\", train.label[9])\n"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "label for human_image: 1\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n3X86L+mwCxqYWkTYdX3Cl03f1vX3zfzc88LDaBVezb8gzkri4qdkJah9tAUhnJypsCchIWE2DFzy\nT09P88uJEhoAYISkHzm96I0XMKaoAZtFpd++BFmG2naaRctJ7YK52qks16VajohSTCcROi7kR6Kh\nNAkjqnyTmGR4nU7ukVK2YyW/O/cLXTztjTnE0m76jYsAAEuWLuV1LZM+aiWo7RQkz6k0qcx0bT98\n0Yd426df+v/6mtuHRXxwxEl+nwZLUpckv58LS2tTTmydhrGa25AL0l0LF2buqBbdxFuYyyF8Iq1q\nJmCTiLSGlGckqUMtzkt6810WuJliHwoR26aemus/dDz3gyT5ExKGFFk9l+r/E8T555+PpUuXYtmy\nZYM65AnjF7/4xRkz3zNprsCZNd8zZa579+7FW2+91de2A/3nB4D169dj165dgzzkCeFMmu+ZNFfg\nzJrvmTTXfpHU/oSEIUX6509IGFIUf/AHf/AHgz7o9ddfP+hDnhDOpPmeSXMFzqz5nklz7QcDt/kT\nEhIWBpLan5AwpBjYP/9TTz2Fyy67DBdffDEmJiYGddi+sW/fPnzsYx/D+Pg4rrzySjz88MMAgMOH\nD+OWW27BJZdcgltuuQXvvDOfKvZTg7Iscd111+E3f/M3ASzsub777ru44447cPnll2N8fBzPPffc\ngp3v1772NVx55ZW46qqr8Nu//duYnJxcsHM9EQzkn78sS/z+7/8+vve97+Hll1/Gt7/9bbz88suD\nOHTfaLVa+OpXv4pXXnkFzz//PL75zW/i5ZdfxsTEBDZs2IA9e/Zgw4YNC+rF9fDDD2N8fJy/L+S5\n3nffffjEJz6Bn/70p3jxxRcxPj6+IOd74MABfOMb38CuXbvw0ksvoSxLbN++fUHO9YRRDwDPPvts\nfeutt/L3Bx54oH7ggQcGceh5Y+PGjfVf//Vf15deemn9xhtv1HVd12+88UZ96aWXnuaZNdi3b199\n88031zt37qw/9alP1XVdL9i5vvfee/XatWvrqqrU+oU43/3799erVq2q33777brT6dSf+tSn6u9/\n//sLcq4nioFI/gMHDmD16tX8fdWqVThw4MAgDj0v7N27F7t378aNN96IN998E2NjYwCAsbExHDp0\n6DTPrsHnPvc5fOUrX1G0ZAt1rq+99hqWLVuGz3zmM7juuuvwe7/3ezh69OiCnO/KlSvxhS98AWvW\nrMHY2BjOPfdc3HrrrQtyrieKgfzz11EutJNNBH9ycOTIEdx+++34+te/jnPOOed0TyeKJ554AsuX\nLz9jQk/dbhcvvPACPvvZz2L37t1YunTpglWb33nnHezYsQOvv/463njjDRw9ehSPPvro6Z7WKcFA\n/vlXrVqFffv28ff9+/fjwgsvHMSh54ROp4Pbb78dd999N2677TYAwIoVK3Dw4EEAwMGDB7F8+fLT\nOUUAwDPPPIPvfve7WLt2LT796U/jb//2b3HPPfcsyLkCzf1ftWoVbrzxRgDAHXfcgRdeeGFBzvcH\nP/gBLrroIixbtgztdhu33XYbnn322QU51xPFQP75b7jhBuzZswevv/46pqensX37dmzcuHEQh+4b\ndV3j3nvvxfj4OD7/+c/z+o0bN2Lbtm0AgG3btmHTpk2na4qMBx98EPv378fevXuxfft23HzzzXj0\n0UcX5FwB4IILLsDq1avx6quvAgB27tyJK664YkHOd82aNXj++edx7Ngx1HWNnTt3Ynx8fEHO9YQx\nKOfCk08+WV9yySX1unXr6j/8wz8c1GH7xt/93d/VAOqrr766vuaaa+prrrmmfvLJJ+u33nqrvvnm\nm+uLL764vvnmm+u33377dE9V4emnn2aH30Ke6+7du+vrr7++vvrqq+tNmzbVhw8fXrDz/dKXvlRf\ndtll9ZVXXlnfc8899eTk5IKd64kgZfglJAwpUoZfQsKQIv3zJyQMKdI/f0LCkCL98yckDCnSP39C\nwpAi/fMnJAwp0j9/QsKQIv3zJyQMKf5/JvxN+WyTMVcAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 600x400 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "263w_dYksmIm",
        "colab_type": "text"
      },
      "source": [
        "## Model Definition\n",
        "\n",
        "``objax.nn.Linear(ndim, 1)`` is a linear neural unit with ``ndim`` inputs and a single output. Given input $\\mathbf{X}$, the output is equal to $\\mathbf{W}\\mathbf{X} + \\mathbf{b}$ where $\\mathbf{W}, \\mathbf{b}$ are the model's parameters. These parameters are available through ``model.vars()``\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t6nVVIM5qHVa",
        "colab_type": "code",
        "colab": {
          "height": 68
        },
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767952860,
          "user_tz": 420,
          "elapsed": 524,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        },
        "outputId": "66e3382d-6fce-4522-c176-494b22e3e5fa"
      },
      "source": [
        "# Settings\n",
        "lr = 0.0001  # learning rate\n",
        "batch = 256\n",
        "epochs = 20\n",
        "\n",
        "model = objax.nn.Linear(ndim, 1)\n",
        "print(model.vars())"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(Linear).b                  1 (1,)\n",
            "(Linear).w              30000 (30000, 1)\n",
            "+Total(2)               30001\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Iz0EhfH6gQcY",
        "colab_type": "text"
      },
      "source": [
        "## Model Inference\n",
        "\n",
        "Now that we have defined the model we can use to classify images. To do so, we call the model with an image from the ``train`` dataset we previously prepared. Notice that we use the image of a human we previously visualized. \n",
        "\n",
        "We get the output of the model by calling ``model()``. We then apply the sigmoid activation function and round the output. Activation outputs lower than or equal to 0.5 are rounded to zero (i.e., horses) whereas outputs larger than 0.5 are rounded to one (i.e., humans). \n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iygPHG0ugPYU",
        "colab_type": "code",
        "colab": {
          "height": 34
        },
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767962130,
          "user_tz": 420,
          "elapsed": 586,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        },
        "outputId": "65cc8342-ff21-4b58-f3dd-f94c8366159c"
      },
      "source": [
        "# This is an image of a human.\n",
        "print(np.round(objax.functional.sigmoid(model(train.image[9]))))"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[1.]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Vyb4dahWhpAW",
        "colab_type": "text"
      },
      "source": [
        "Considering that we initialized the model with random weights, it should not come as a surprise that the model may misclassify a human as a horse. "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kiQ8IWTXuJCq",
        "colab_type": "text"
      },
      "source": [
        "## Optimizer and Loss Function\n",
        "\n",
        "In this example we use the ``objax.optimizer.SGD`` optimizer. Next, we define the loss function we will use to optimize the network. In this case we use the cross entropy loss function. Note that we use `objax.functional.loss.sigmoid_cross_entropy_logits` because we perform binary classification."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MroptKwQuIDV",
        "colab_type": "code",
        "colab": {},
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767964790,
          "user_tz": 420,
          "elapsed": 529,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        }
      },
      "source": [
        "opt = objax.optimizer.SGD(model.vars())\n",
        "\n",
        "# Cross Entropy Loss\n",
        "def loss(x, label):\n",
        "  return objax.functional.loss.sigmoid_cross_entropy_logits(model(x)[:, 0], label).mean()"
      ],
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xN5TYLlEuXhi",
        "colab_type": "text"
      },
      "source": [
        "## Back Propagation and Gradient Descent\n",
        "\n",
        "``objax.GradValues`` calculates the gradient of ``loss`` wrt ``model.vars()``. If you want to learn more about gradients read the [Understanding Gradients](../advanced/gradients.html#understanding-gradients) in-depth topic.\n",
        "\n",
        "The ``train_op`` function implements the core of backward propagation and gradient descent. First, we calculate the gradient ``g`` and then pass it to the optimizer which updates the model’s weights."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "25t6iuxfubBq",
        "colab_type": "code",
        "colab": {},
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767967528,
          "user_tz": 420,
          "elapsed": 479,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        }
      },
      "source": [
        "gv = objax.GradValues(loss, model.vars())\n",
        "\n",
        "def train_op(x, label):\n",
        "  g, v = gv(x, label)  # returns gradients, loss\n",
        "  opt(lr, g)\n",
        "  return v\n",
        "\n",
        "# This line is optional: it is compiling the code to make it faster.\n",
        "train_op = objax.Jit(train_op, gv.vars() + opt.vars())"
      ],
      "execution_count": 8,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eAo8BWvrv0t5",
        "colab_type": "text"
      },
      "source": [
        "## Training and Evaluation Loop\n",
        "\n",
        "For each of the training epochs we process all the training data, contained in the train dictionary, in batches of ``batch`` size. At the end of each epoch we compute the classification accuracy by comparing the model’s predictions over the test data to the ground truth labels.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6xqrHmyvqKO3",
        "colab_type": "code",
        "colab": {
          "height": 357
        },
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767937132,
          "user_tz": 420,
          "elapsed": 2163,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        },
        "outputId": "5afefac7-fab3-43a1-fbc6-a8906d35dc15"
      },
      "source": [
        "for epoch in range(epochs):\n",
        "  # Train\n",
        "  avg_loss = 0\n",
        "  # randomly shuffle training data\n",
        "  shuffle_idx = np.random.permutation(train.image.shape[0])\n",
        "  for it in range(0, train.image.shape[0], batch):\n",
        "    sel = shuffle_idx[it: it + batch]\n",
        "    avg_loss += float(train_op(train.image[sel], train.label[sel])[0]) * len(sel)\n",
        "  avg_loss /= it + batch\n",
        "\n",
        "  # Eval\n",
        "  accuracy = 0\n",
        "  for it in range(0, test.image.shape[0], batch):\n",
        "    x, y = test.image[it: it + batch], test.label[it: it + batch]\n",
        "    accuracy += (np.round(objax.functional.sigmoid(model(x)))[:, 0] == y).sum()\n",
        "  accuracy /= test.image.shape[0]\n",
        "  print('Epoch %04d  Loss %.2f  Accuracy %.2f' % (epoch + 1, avg_loss, 100 * accuracy))"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch 0001  Loss 0.25  Accuracy 82.81\n",
            "Epoch 0002  Loss 0.25  Accuracy 82.81\n",
            "Epoch 0003  Loss 0.25  Accuracy 83.59\n",
            "Epoch 0004  Loss 0.25  Accuracy 82.81\n",
            "Epoch 0005  Loss 0.25  Accuracy 82.03\n",
            "Epoch 0006  Loss 0.25  Accuracy 80.86\n",
            "Epoch 0007  Loss 0.25  Accuracy 80.86\n",
            "Epoch 0008  Loss 0.24  Accuracy 80.86\n",
            "Epoch 0009  Loss 0.24  Accuracy 82.03\n",
            "Epoch 0010  Loss 0.24  Accuracy 83.20\n",
            "Epoch 0011  Loss 0.24  Accuracy 82.03\n",
            "Epoch 0012  Loss 0.24  Accuracy 80.86\n",
            "Epoch 0013  Loss 0.24  Accuracy 81.25\n",
            "Epoch 0014  Loss 0.24  Accuracy 83.59\n",
            "Epoch 0015  Loss 0.24  Accuracy 84.38\n",
            "Epoch 0016  Loss 0.24  Accuracy 85.16\n",
            "Epoch 0017  Loss 0.24  Accuracy 84.77\n",
            "Epoch 0018  Loss 0.24  Accuracy 83.98\n",
            "Epoch 0019  Loss 0.24  Accuracy 83.20\n",
            "Epoch 0020  Loss 0.24  Accuracy 83.59\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fqNmaHmUfnDX",
        "colab_type": "text"
      },
      "source": [
        "## Model Inference After Training\n",
        "\n",
        "Now that the network is trained we can retry classification example above:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OLChKdTKhlPf",
        "colab_type": "code",
        "colab": {
          "height": 34
        },
        "executionInfo": {
          "status": "ok",
          "timestamp": 1597767974572,
          "user_tz": 420,
          "elapsed": 483,
          "user": {
            "displayName": "Andreas Terzis",
            "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgyMHDRrpyzqWeAqfNYUCBAV6wEwWfRfuCzPdQSSg=s64",
            "userId": "11574137277392387833"
          }
        },
        "outputId": "17542060-0fa2-43a7-af16-72a8f33bf012"
      },
      "source": [
        "print(np.round(objax.functional.sigmoid(model(train.image[9]))))"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[1.]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ix8W-GEhlqkL",
        "colab_type": "text"
      },
      "source": [
        "## Next Steps\n",
        "\n",
        "We saw how we can define, use, and train a very simple model in Objax to classify images of humans and horses. Next, we will learn how to [create custom models](Custom_Networks.html) to classify handwritten digits."
      ]
    }
  ]
}
